package edu.udel.mboch.towerdefense;

import java.util.ArrayList;

public class SingleAIPlayer extends Player implements Actor
{
	private static final long serialVersionUID = -351434033605262595L;

	public SingleAIPlayer(String name)
	{
		super(name);
	}
	
	public SingleAIPlayer(String name, int cash, int income, int lives, ArrayList<Tower> towers)
	{
		super(name, cash, income, lives, towers);
	}
	
	public ArrayList<TDMove> getAllValidMoves(TDState state)
	{
		ArrayList<TDMove> moves = new ArrayList<TDMove>();
		for(int i = 0; i<Grid.MAX_Y; i++)
			for(int j = 0; j<Grid.MAX_X; j++)
			{
				if(cash>=Tower.BASIC_COST)
				{
					PlayerBuildMove move = new PlayerBuildMove(new BasicTower(new Position(j,i)));
					if(move.isValid(state))
						moves.add(move);
				}
				if(cash>=Tower.HEAVY_COST)
				{
					PlayerBuildMove move = new PlayerBuildMove(new HeavyTower(new Position(j,i)));
					if(move.isValid(state))
						moves.add(move);
				}
				if(cash>=Tower.SLOW_COST)
				{
					PlayerBuildMove move = new PlayerBuildMove(new SlowTower(new Position(j, i)));
					if(move.isValid(state))
						moves.add(move);
				}
				if(cash>=Tower.SPLASH_COST)
				{
					PlayerBuildMove move = new PlayerBuildMove(new SplashTower(new Position(j, i)));
					if(move.isValid(state))
						moves.add(move);
				}
			}
		return moves;
	}
	
	public TDMove getNextMove(TDState state)
	{
		int maxScore = Integer.MIN_VALUE;
		ArrayList<TDMove> possibleMoves = new ArrayList<TDMove>();
		for(TDMove move : getAllValidMoves(state))
		{
			SinglePlayerTDState copy = (SinglePlayerTDState)state.copy();
			move.make(copy);
			copy.getPlayer().getTowers().add(((PlayerBuildMove)move).getTower());
			int score = copy.getPlayer().getHeuristicScore(copy);
			if(score>maxScore)
				possibleMoves.clear();
			if(score>=maxScore)
			{
				possibleMoves.add(move);
				maxScore = score;
			}
		}
		if(possibleMoves.size() > 0)
		{
			PlayerBuildMove move = (PlayerBuildMove)possibleMoves.get((int)(Math.random()*possibleMoves.size()));
			cash -= move.getTower().getCost();
			return move;
		}
		return null;
	}

	public int getHeuristicScore(TDState state)
	{
		int score = 0;
		for(Tower t : towers)
		{
			int gridCovered = 0;
			for(Position p : t.getPositionsInRange())
			{
				if(!state.getGrid().getTerrain()[p.y()][p.x()].isBuildable())
					gridCovered++;
			}
			score += gridCovered*t.getCost();
		}
		return score;
	}
	
	public SingleAIPlayer copy()
	{
		ArrayList<Tower> towersCopy = new ArrayList<Tower>();
		for(Tower t : towers)
			towersCopy.add(t.copy());
			
		return new SingleAIPlayer(name, cash, income, lives, towersCopy);
	}
}
